#!/bin/bash
LINE=40
COLUMN=80
side='$'
ss='+'
number=10
star_x=0
star_y=0
star='*'
declare -a snake_x
declare -a snake_y
declare -i snake_len=0

function show_char(){
	echo -en "\033[$1;$2H\033[32;40m\033[1m$3"
        echo -en "\033[0m"
}

function show_line(){
	local line=$1
	local char=$2
	for((i=1;i<=$COLUMN;i++))
	do
		echo -en "\033[${line};${i}H\033[1;31;40m${char}"
                echo  -en "\033[0m"
	done

}

function show_column(){
	local column=$1
        local char=$2
        for((i=1;i<=$LINE;i++))
	do       
		echo -en "\033[${i};${column}H\033[1;31;40m${char}"
	done
	echo  -en "\033[0m"
}
function show_help(){
	start_line=$((LINE+1))
        echo -en "\033[$((start_line+1));1H\033[32m=========================================="
	echo -en "\033[$((start_line+2));10H\033[32mw  up"
	echo -en "\033[$((start_line+3));10H\033[32ms  down"
	echo -en "\033[$((start_line+4));10H\033[32mw  left"
	echo -en "\033[$((start_line+5));10H\033[32ms  right"
	echo -en "\033[$((start_line+6));10H\033[32mq  quit"
	echo -en "\033[$((start_line+7));10H\033[32mp  pause and start"
        echo -en "\033[$((start_line+8));1H\033[32m=========================================="
	echo -en "\033[0m"
}

function backimage(){
	show_line  1 $side
	show_line $LINE $side
	show_column 1 $side
	show_column $COLUMN $side
        show_help
}

function dead(){
	clear
	echo  -en  "\033[20;40H\033[36;40mGAME OVER!!!"
        echo  -en  "\033[0m"
	echo -e "\n\n\n\n\n\n"
	exit 0
}

function move(){
	for((i=$((snake_len));i>=1;i--))
        do
        	snake_x[$((i+1))]=${snake_x[$i]}
                snake_y[$((i+1))]=${snake_y[$i]}
        done
}

function check(){
	#border check
	if [ ${snake_x[1]} -le 1 ] ; then
		dead
	fi

	if [ ${snake_x[1]} -ge $LINE ] ; then
                dead
        fi

	if [ ${snake_y[1]} -le 1 ] ; then
               dead
        fi

	if [ ${snake_y[1]} -ge $COLUMN ] ; then
                        dead
        fi
	#body check
	for((i=2;i<=$snake_len;i++))
	do
		if [[ ${snake_x[i]} -eq ${snake_x[1]} && ${snake_y[i]} -eq ${snake_y[1]} ]];then
			dead
	 	fi
	done
}

#star

function range(){
      x=$1
      y=$2
      match=0
       x_range=$((x - snake_x[1] ))
       y_range=$((y - snake_y[1] ))
       if [ $x_range -lt 0 ] ; then
            x_range=$((0-x_range))
       fi
       if [ $y_range -lt 0 ] ; then
            y_range=$((0-y_range))
       fi
       range=$((x_range+y_range))
       
       if [ $range -lt 5 ] ;then
            match=1
       fi
       return $match
}

function coincide(){
    x=$1
    y=$2
    match=0
   for((j=1;j<=$snake_len;j++))
   do 
        if [ ${snake_x[$j]} -eq $x -a ${snake_y[$j]} -eq $y ] ;then
	     match=1
	     break
        fi
   done
   return $match

}


function make_star(){
   while true
         do
	   x=$((RANDOM%(LINE-2)+2)) 
	   y=$((RANDOM%(COLUMN-2)+2)) 
	   range $x $y
	   match=$?
	   if [ $match -eq 0 ]; then
		coincide $x $y
                match1=$?
		if [ $match1 -eq 0 ]; then
                    star_x=$x
                    star_y=$y
		    echo -en "\033[${x};${y}H\033[32;46m\033[1m${star}"
		    echo  -en "\033[0m"
                    return
                fi
	   fi
   	done
  
}

function eat(){
	if [ ${snake_x[1]} -eq $star_x -a ${snake_y[1]} -eq $star_y ];then
        	snake_len=$((snake_len+1))
		snake_x[$((snake_len+1))]=$((LINE+1))
                snake_y[$((snake_len+1))]=$COLUMN
                make_star
	fi

}

function pause(){
	read -s -n 1  tmpcmd
}


#main

clear
backimage
make_star

ops='a'
head="<"
start=49
for((j=1;j<=$number;j++))
do
	snake_x[$j]=20
	snake_y[$j]=$((start+j))
        if [ $j -eq 1 ];then
		show_char 20 $((start+j)) $head
        else
		show_char 20 $((start+j)) $ss
        fi

	let snake_len++
	
done

while true
do
	read -s -n 1 -t 0.2 tmpops 
        if   [[ $tmpops == "a" || $tmpops == "d" ]]; then
            if [[ $ops == "w" || $ops == "s" ]]; then
                ops=$tmpops
            fi
        elif [[ $tmpops == "w" || $tmpops == "s" ]]; then
            if [[ $ops == "a" || $ops == "d" ]]; then
            	ops=$tmpops
            fi
        elif [[ $tmpops == "q" ]];then
              dead
        elif [[ $tmpops == "p" ]];then
 	      pause
	fi
        
	case $ops in 
	w)
		move
    		eat
		snake_x[1]=$((snake_x[1]-1))
		head="^"
		;;
	s)
		move
                eat
                snake_x[1]=$((snake_x[1]+1))
		head="v"
                ;;
	 a) 
		move
                eat
                snake_y[1]=$((snake_y[1]-1))
 	        head="<"
                ;;
	d)
		move
	        eat
		snake_y[1]=$((snake_y[1]+1))
 	
  	      head=">"
                ;;
	*)
	;;
	esac
        check
	show_char  ${snake_x[$((snake_len+1))]}  ${snake_y[$((snake_len+1))]} " "
	show_char  ${snake_x[2]} ${snake_y[2]} "$ss"
	show_char  ${snake_x[1]} ${snake_y[1]} "$head"
done
